package com.juyu.miliao.api.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.api.constant.NewYearDayActivitySignInEnum;
import com.juyu.miliao.api.constant.PrizeInfoEnum;
import com.juyu.miliao.api.constant.PrizeTypeEnum;
import com.juyu.miliao.api.dao.mysql.BillDetailDao;
import com.juyu.miliao.api.dao.mysql.UserInfoDao;
import com.juyu.miliao.api.dao.mysql.UserWalletDao;
import com.juyu.miliao.api.dao.redis.usercache.UserCacheVo;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.BillDetail;
import com.juyu.miliao.api.domain.User;
import com.juyu.miliao.api.domain.UserWallet;
import com.juyu.miliao.api.domain.dto.UserLuckDrawInfoDTO;
import com.juyu.miliao.api.domain.vo.*;
import com.juyu.miliao.api.util.RandomUtil;
import com.juyu.miliao.common.constant.FirstRechargeTypeEnum;
import com.juyu.miliao.common.constant.NewYearDayActivityRedisKey;
import com.juyu.miliao.common.constant.SecondRechargeTypeEnum;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author xuanqicheng
 * @create 2018-26-09:19
 */
@Service
@Slf4j
public class NewYearDayActivityService {

    public static final List<PrizeInfoVo> LUCK_DRAW_VO_LIST = new ArrayList<>(0);

    static {
        LUCK_DRAW_VO_LIST.add(new PrizeInfoVo().setTitle(PrizeInfoEnum.THE_FIRST_PRIZE.getTitle())
                .setMessage(PrizeInfoEnum.THE_FIRST_PRIZE.getMessage()));
        LUCK_DRAW_VO_LIST.add(new PrizeInfoVo().setTitle(PrizeInfoEnum.THE_SECOND_PRIZE.getTitle())
                .setMessage(PrizeInfoEnum.THE_SECOND_PRIZE.getMessage()));
        LUCK_DRAW_VO_LIST.add(new PrizeInfoVo().setTitle(PrizeInfoEnum.THE_THIRD_PRIZE.getTitle())
                .setMessage(PrizeInfoEnum.THE_THIRD_PRIZE.getMessage()));
        LUCK_DRAW_VO_LIST.add(new PrizeInfoVo().setTitle(PrizeInfoEnum.THE_ENCOURAGE_PRIZE.getTitle())
                .setMessage(PrizeInfoEnum.THE_ENCOURAGE_PRIZE.getMessage()));
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserInfoCache userInfoCache;

    @Autowired
    private UserWalletDao userWalletDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private BillDetailDao billDetailDao;


    public void getSignIn(Long userId) {
        String key = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_SIGN_IN + LocalDate.now().toString();

        boolean bl = stringRedisTemplate.opsForSet().isMember(key, Long.toString(userId));

        if (!bl) {
            //用户没有签到，进行用户签到
            stringRedisTemplate.opsForSet().add(key, Long.toString(userId));
            //用户增加抽奖次数
            String luckDrawNumberKey = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_LUCK_DRAW_NUMBERS_BY_USER + userId;

            stringRedisTemplate.opsForValue().increment(luckDrawNumberKey, 1);
        }

    }

    /**
     * 查看用户今天是否签到过
     *
     * @param userId
     * @return
     */
    public NewYearDayActivitySignInVo getNewYearDayActivityByUserId(Long userId) {

        NewYearDayActivitySignInVo newYearDayActivitySignInVo = new NewYearDayActivitySignInVo();

        String key = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_SIGN_IN + LocalDate.now().toString();

        boolean bl = stringRedisTemplate.opsForSet().isMember(key, Long.toString(userId));

        //默认没有签到
        int signIn = NewYearDayActivitySignInEnum.USER_NOT_SIGN_IN.getCode();

        if (bl) {
            //用户已签到
            signIn = NewYearDayActivitySignInEnum.USER_SIGN_IN.getCode();
        }

        UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(userId);
        log.info("用户:{},是否是vip:{}",userId,userCacheVo.getIsVip());
        if(userCacheVo.getIsVip()==1 ||userCacheVo.getIsSvip()==1 || userCacheVo.getIsPlatinumVip()==1){

            String vipLoginKey = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_VIP_LOGIN+LocalDate.now().toString();
            boolean vipLoginBl = stringRedisTemplate.opsForSet().isMember(vipLoginKey,Long.toString(userId));
            log.info("用户:{},是否vip登录过：{}",userId,vipLoginBl);
            if(!vipLoginBl){

                //进行vip登录
                stringRedisTemplate.opsForSet().add(vipLoginKey, Long.toString(userId));

                //用户没有登录
                String luckDrawNumberKey = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_LUCK_DRAW_NUMBERS_BY_USER + userId;
                //vip 登录自增3次
                stringRedisTemplate.opsForValue().increment(luckDrawNumberKey, 3);
                log.info("用户:{},VIP登录添加3次抽奖机会",userId);
            }
        }

        newYearDayActivitySignInVo.setSignIn(signIn).setPrizeInfoVos(LUCK_DRAW_VO_LIST);

        return newYearDayActivitySignInVo;
    }

    /**
     * @param userId,用户id
     * @param hostId,主播id
     * @return
     */
    public Object getLuckDraw(Long userId, Long hostId) {
        NewYearDayActivityLuckDrawVo newYearDayActivityLuckDrawVo = new NewYearDayActivityLuckDrawVo();
        //查看用户是否有充值次数
        String luckDrawNumberKey = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_LUCK_DRAW_NUMBERS_BY_USER + userId;

        String numbers = stringRedisTemplate.opsForValue().get(luckDrawNumberKey);

        if (!StringUtils.isEmpty(numbers) && Long.parseLong(numbers) > 0) {
            //获取主播对象
            UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(hostId);

            HostUserVo hostUserVo = new HostUserVo();

            BeanUtils.copyProperties(userCacheVo, hostUserVo);

            newYearDayActivityLuckDrawVo.setHostInfo(hostUserVo);

            //获取用户活动充值信息对象
            String chargeKey = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_CHARGE_BY_USER_USER;
            String hashKey = Long.toString(userId);
            String temp = (String) stringRedisTemplate.opsForHash().get(chargeKey, hashKey);
            if (!StringUtils.isEmpty(temp)) {
                UserLuckDrawInfoDTO obj = JSONObject.parseObject(temp, UserLuckDrawInfoDTO.class);
                //判断用户用户首充状态
                if (obj.getFirstRechargeType() == FirstRechargeTypeEnum.SUCCESS_FIRST_RECHARGE_AND_NO_LOTTERY.getCode()) {
                    //TODO 首充状态为1，返还用户中奖38个金币,然后更改用户首充状态为2，添加抽奖时间,减一次抽奖次数
                    //更改状态，添加抽奖时间
                    obj.setFirstRechargeType(FirstRechargeTypeEnum.SUCCESS_FIRST_RECHARGE_AND_SUCCESS_LOTTERY.getCode());

                    obj.setFirstLuckDrawTime(LocalDateTime.now());

                    stringRedisTemplate.opsForHash().put(chargeKey, hashKey, JSONObject.toJSONString(obj));

                    getLuckDrawVoAndSubtractionLuckDrawNumber(luckDrawNumberKey, newYearDayActivityLuckDrawVo,
                            PrizeTypeEnum.WINNING_THE_PRIZE.getCode(), PrizeInfoEnum.THE_THIRD_PRIZE.getMessage());
                    //加38金币
                    addGold(userId, 38);
                } else if (obj.getSecondRechargeType() == SecondRechargeTypeEnum.SUCCESS_SECOND_RECHARGE_AND_NO_LOTTERY.getCode()) {
                    //TODO 二次充值状态为1，返还用户中奖8个金币,然后更改用户二次充值状态为2，添加抽奖时间,减一次抽奖次数
                    obj.setSecondRechargeType(SecondRechargeTypeEnum.SUCCESS_SECOND_RECHARGE_AND_SUCCESS_LOTTERY.getCode());

                    obj.setSecondLuckDrawTime(LocalDateTime.now());

                    stringRedisTemplate.opsForHash().put(chargeKey, hashKey, JSONObject.toJSONString(obj));

                    getLuckDrawVoAndSubtractionLuckDrawNumber(luckDrawNumberKey, newYearDayActivityLuckDrawVo,
                            PrizeTypeEnum.WINNING_THE_PRIZE.getCode(), PrizeInfoEnum.THE_ENCOURAGE_PRIZE.getMessage());
                    //加18个金币
                    addGold(userId, 18);
                } else {
                    // 返还用户没有中奖
                    getLuckDrawVoAndSubtractionLuckDrawNumber(luckDrawNumberKey, newYearDayActivityLuckDrawVo,
                            PrizeTypeEnum.NOT_THE_PRIZE.getCode(), PrizeInfoEnum.THE_NOT_PRIZE.getMessage());
                }
            } else {
                // 返还用户没有中奖
                getLuckDrawVoAndSubtractionLuckDrawNumber(luckDrawNumberKey, newYearDayActivityLuckDrawVo,
                        PrizeTypeEnum.NOT_THE_PRIZE.getCode(), PrizeInfoEnum.THE_NOT_PRIZE.getMessage());
            }
        } else {
            throw new ConsumeRuntimeException("用户没有翻牌次数，请签到或充值");
        }
        return newYearDayActivityLuckDrawVo;
    }

    /**
     * 设置返还信息
     *
     * @param newYearDayActivityLuckDrawVo, 抽奖次数key
     * @param prizeType                     中奖状态,1:中奖，2：没有中奖
     * @param message
     */
    private void getLuckDrawVoAndSubtractionLuckDrawNumber(String luckDrawNumberKey,
                                                           NewYearDayActivityLuckDrawVo newYearDayActivityLuckDrawVo,
                                                           int prizeType, String message) {

        stringRedisTemplate.opsForValue().increment(luckDrawNumberKey, -1);

        LuckDrawVo luckDrawVo = new LuckDrawVo();

        luckDrawVo.setPrizeType(prizeType);

        luckDrawVo.setMessage(message);

        newYearDayActivityLuckDrawVo.setDetail(luckDrawVo);
    }


    /**
     * 保存金币
     *
     * @param userId
     * @param gold
     */
    private void addGold(Long userId, int gold) {
        UserWallet userWallet = new UserWallet();
        userWallet.setUserId(userId);
        userWallet.setDeposit(gold);
        // 保存消费记录
        userWalletDao.reviseDeposit(userWallet);
        log.info("用户：{}抽奖获取金币：{}个", userId, gold);

        BillDetail billDetail = new BillDetail();
        //抽奖
        billDetail.setRecordType(15);
        billDetail.setInUserId(userId);
        billDetail.setDiamond(0);
        // 消费金币数
        billDetail.setSpend(gold);
        billDetailDao.insertBillDetail(billDetail);

        log.info("用户：{}抽奖账单：{}",userId,billDetail);
    }

    /**
     * 获取剩余抽奖次数
     *
     * @param userId
     * @return
     */
    public Object getNumbers(Long userId) {
        Map<String, Long> map = new HashMap<>();
        long number = 0;
        String key = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_LUCK_DRAW_NUMBERS_BY_USER + userId;
        String temp = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(temp)) {
            number = Long.parseLong(temp);
        }
        map.put("numbers", number);
        return map;
    }

    /**
     * 获取主播列表
     *
     * @return
     */
    public Object getHostUserList() {
        String key = NewYearDayActivityRedisKey.NEW_YEAR_DAY_ACTIVITY_HOST_USER;
        String temp = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(temp)) {

            JSONArray tempList = JSONObject.parseArray(temp);

            List<Long> list = new ArrayList<>();
            for (int i = 0; i < tempList.size(); i++) {

                list.add(tempList.getLong(i));
            }

            List<Long> userIdList = new ArrayList<>(0);

            userIdList = getUserIds(list);

            List<User> users = userInfoDao.getQualityHostByUserIds(userIdList);
            List<Map<String, Object>> resultList = new ArrayList<>();
            getResultVo(users, resultList);
            return resultList;
        } else {
            List<Long> userIdList = new ArrayList<>(0);

            List<Long> list = userInfoDao.getHostUserList();
            if (list.size() <= 100) {
                userIdList = getUserIds(list);
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(list));
            } else {
                List<Long> sList = list.subList(0, 100);

                userIdList = getUserIds(list);

                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(sList),15, TimeUnit.MINUTES);
            }

            List<User> users = userInfoDao.getQualityHostByUserIds(userIdList);
            List<Map<String, Object>> resultList = new ArrayList<>();
            getResultVo(users, resultList);
            return resultList;
        }


    }

    private void getResultVo(List<User> users, List<Map<String, Object>> resultList) {
        for (User user : users) {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", user.getUserId());
            map.put("picUrl", user.getPicUrl());
            map.put("signature",user.getSignature());
            resultList.add(map);
        }
    }


    private List<Long> getUserIds(List<Long> list) {
        List<Long> userIdList = new ArrayList<>(0);
        int[] randomCommons = RandomUtil.randomCommon(0,list.size()-1,8);
        for (int i = 0; i < randomCommons.length; i++) {
            long userId = list.get(randomCommons[i]);
            userIdList.add(userId);
        }
        return userIdList;
    }



    /**
     * 获取获奖信息
     * @return
     */
    public List<String> getWinInfo() {
        List<String> list = new ArrayList<>();
        list.add("枪嘣狗友刚刚翻中1888元");
        list.add("傲气稳了全场刚刚翻中888元");
        list.add("造梦怪咖丶o刚刚翻中1888元");
        list.add("朂酷⑶suι半刚刚翻中38金币");
        list.add("帝王不怀旧刚刚翻中1888元");
        list.add("揚鞭筞野馬刚刚翻中888元");
        list.add("一袍清酒付刚刚翻中888元");
        list.add("刚刚翻中1888元");
        list.add("西风乍起刚刚翻中8金币");
        list.add("孤老序刚刚翻中1888元");
        list.add("梦一场荒唐刚刚翻中18金币");
        list.add("打酱油滴小男孩刚刚翻中1888元");
        list.add("烈烈秦汉刚刚翻中1888元");
        list.add("壹惗両三哖刚刚翻中1888元");
        list.add("几叶到寒刚刚翻中18金币");
        list.add("一个小孩刚刚翻中38金币");
        list.add("ぐ温柔行凶者刚刚翻中1888元");
        list.add("扛刀走情场刚刚翻中18金币");
        list.add("青烟小生刚刚翻中1888元");
        list.add("巧了我就是酷メ刚刚翻中38金币");
        return list;
    }
}
